//
// Created by A on 2018/7/4.
//

#include <stdlib.h>
#include <memory.h>
#include <printf.h>
#include "MemRecoder.h"
#include "RecoderList.h"

MemOperateNode *head = NULL;
MemOperateNode *tail = NULL;

list_node *leakList = NULL;

MemOperateNode *generateNode(char *des, int desLen, char *operate, long ptr) {
    size_t size = sizeof(MemOperateNode);
    MemOperateNode *item = malloc(size);
    memset(item, 0, size);

    item->description = malloc((size_t) desLen);
    memset(item->description, 0, desLen);
    strcpy(item->description, des);

    item->descriptionLen = desLen;

    item->operate = operate;

    item->ptrAddress = ptr;

    return item;
}


void recordMalloc(char *des, int desLen, long ptr) {
    if (head == NULL) {
        head = generateNode(des, desLen, Malloc, ptr);
        head->next = NULL;
        tail = head;
    } else {
        MemOperateNode *item = generateNode(des, desLen, Malloc, ptr);
        tail->next = item;
        tail = item;
    }

    //添加到可能是leak的记录中
    if (leakList == NULL) {
        leakList = list_create(tail);
    } else {
        list_insert_after(leakList, tail);
    }
}

void recordFree(char *des, int desLen, long ptr) {
    if (head == NULL) {
        head = generateNode(des, desLen, Free, ptr);
        head->next = NULL;
        tail = head;
    } else {
        MemOperateNode *item = generateNode(des, desLen, Free, ptr);
        tail->next = item;
        tail = item;
    }

    //根据地址，移除之前malloc的信息
    list_node *current = leakList;
    list_node *matchItem = NULL;
    while (current != NULL) {
        MemOperateNode *item = current->data;
        if (item->ptrAddress == tail->ptrAddress) {
            matchItem = current;
            break;
        }

        current = current->next;
    }

    if (matchItem != NULL) {
        list_remove(&leakList, matchItem);
    }

}

void releaseRecord() {
    MemOperateNode *current = head;
    while (current != NULL) {

        MemOperateNode *needFree = current;
        current = needFree->next;

        free(needFree->description);
        free(needFree);
    }

    if(leakList != NULL) {
        list_destroy(&leakList);
    }
}


void printAllRecord() {
    MemOperateNode *current = head;
    while (current != NULL) {

        MemOperateNode *printNode = current;
        printf("%s\n", printNode->description);

        current = printNode->next;
    }
}

void printLeakRecord() {
    list_node *current = leakList;
    while (current != NULL) {

        MemOperateNode *printNode = current->data;
        printf("%s\n", printNode->description);

        current = current->next;
    }
}

void dumpAllRecord(char *filePath) {

}

void dumpLeakRecord(char *filePath) {

}
